package com.springboot.jdk.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Socket Demo案例
 *
 * @author: zr
 * @date: 2021-10-21
 */
public class SocketServer {

    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = new ServerSocket(9000);

        // 阻塞住，一直等到有其他人跟他建立连接
        Socket socket = serverSocket.accept();

        // 如果有一个客户端跟他发生了TPC三次握手，尝试建立一个连接
        // 这里会构建出来一个Socket， 这个Socket就代表了跟某个客户端的一个TPC连接，Socket连接

        // 如果有人要跟你要建立TCP连接，接下来基于TCP协议来传输数据，发送一个一个的TPC包过来
        // 此时必然是跟你的某个服务器程序的端口号建立的连接

        // 客户端是跟你的  ServerSocket 之间，互相传递3次握手的TCP包，连接就建立，互相交换一些数据

        // 接下来，一旦建立了TCP连接之后
        // 客户单就会通过IO流的方式发送数据过来，无限的流
        // 所以说底层的tCP协议会将 流式的数据拆分为一个一个的TPC包，包括在IP包里面，通过以太包
        // 最后通过底层的网络硬件设备以及以太网协议，发送数据给你发送过来

        InputStream inputStream = socket.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        OutputStream outputStream = socket.getOutputStream();

        char[] buf = new char[1024 * 1024];
        int len = inputStreamReader.read(buf);

        // Socket 的输入流相当于不停的读取人家通过TCP协议发送过来的一个一个的TCP包
        // 将TCP包中的数据通过IO输入流的方式提供给你
        // 你就可以通过IO输入流的方式把TCP包的数据读取出来放入到JVM内存的一个缓存组中。

        while (len != -1) {
            String s = new String(buf, 0, len);
            System.out.println("服务端接收到了请求：" + s);
            // 服务端收到这么一个请求，就发送一个响应回去
            outputStream.write("收到，收到".getBytes());
            // 再次尝试读取 数据
            len = inputStreamReader.read(buf);
            // 你需要反复的去读取socket传输流传输过来的数据
            // 因为人家是不停的用流的方式发送数据过来的，你需要不停的读取
            // buf 仅仅是1kb，可能你才读取了1kb的数据
            // 后面可能还跟了几百kb的数据，所以需要你不停的读取
        }

        // 意思就是说，通过IO流发送响应数据会去，
        // 此时在底层就会把你响应数据拆分为一个一个的TCP包，回传会去
        // 客户端可以接受到你发送的TCP包

        outputStream.close();
        inputStreamReader.close();
        socket.close();
        serverSocket.close();
    }
}
